﻿namespace StockSharp.Algo.Indicators.Oscillator
{
	using System.ComponentModel;

	using StockSharp.Algo.Candles;
	using StockSharp.Algo.Indicators.Misc;

	/// <summary>
	/// Индекс товарного канала.
	/// </summary>
	[DisplayName("CCI")]
	[Description("Индекс товарного канала.")]
	public class CommodityChannelIndex : LengthIndicator<decimal>
	{
		private readonly MeanDeviation _mean = new MeanDeviation();

		/// <summary>
		/// Создать <see cref="CommodityChannelIndex"/>.
		/// </summary>
		public CommodityChannelIndex()
			: base(typeof(Candle))
		{
		}

		/// <summary>
		/// Длина периода.
		/// </summary>
		public override int Length
		{
			get
			{
				return _mean.Length;
			}
			set
			{
				_mean.Length = value;
			}
		}

		/// <summary>
		/// Сформирован ли индикатор.
		/// </summary>
		public override bool IsFormed { get { return _mean.IsFormed; } }

		/// <summary>
		/// Обработать входное значение.
		/// </summary>
		/// <param name="input">Входное значение.</param>
		/// <returns>Результирующее значение.</returns>
		protected override decimal OnProcess(IIndicatorValue input)
		{
			var candle = input.GetValue<Candle>();

			var aveP = (candle.HighPrice + candle.LowPrice + candle.ClosePrice) / 3m;

			var meanValue = _mean.Process(new DecimalIndicatorValue(aveP) {IsFinal = input.IsFinal});

			if (IsFormed)
			{
                if (meanValue.GetValue<decimal>() != 0)
                {
                    return (aveP - _mean.Sma.GetCurrentValue()) / (0.015m * meanValue.GetValue<decimal>());
                }
                else
                {
                    return 0;
                }
			}
			else
			{
				return this.GetCurrentValue();
			}
		}
	}
}